Reduce copies of S7 class objects - #743
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
|
I benchmarked this locally against Marginal retained memory per instance:
So the PR achieves the intended result: per-instance class storage becomes a flat 168 B rather than growing with the class hierarchy. Construction timings (average of the two median runs):
|
|
Follow-up class-operation benchmarks, now in a separate
This confirms the expected downstream benefit of shared class identity: operations whose first step is an identity comparison become roughly 24–35× faster. Direct class retrieval is slightly slower because the C accessor must dereference the environment-backed class reference. |
|
I also prototyped having S7-generated constructors pass the class reference explicitly to
So explicit passing saves about 0.6 µs per |
| # the reference instead of the closure, avoiding `sys.function()` and ensuring | ||
| # that objects serialized together share a single copy of their class. | ||
| new_class_ref <- function() { | ||
| ref <- new.env(parent = emptyenv()) |
There was a problem hiding this comment.
My guess is that if we set hash = FALSE here we'll see slightly better performance. (probably above, in the constructor_env, too)
| x <- Foo() | ||
| y <- Foo() | ||
|
|
||
| x_ref <- attr(x, "_S7_class", exact = TRUE) |
There was a problem hiding this comment.
Do we have a principled policy for when to use the underscore prefix and when to use the dot prefix?
|
I set
Focused |
Fixes #742.
This prototype stores an environment-backed class reference on ordinary S7 instances instead of the class closure itself. This avoids the deep copy from
sys.function()and ensuressaveRDS()saves a single copy of the object.The tests use a small internal C
obj_addr()helper to assert reference identity directly.